package com.huizu.project.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huizu.common.core.domain.AjaxResult;
import com.huizu.common.core.domain.entity.SysUser;
import com.huizu.common.core.redis.RedisCache;
import com.huizu.common.core.redis.RedisRank;
import com.huizu.common.exception.ServiceException;
import com.huizu.common.utils.DateUtils;
import com.huizu.common.utils.PassWordVerifyUtil;
import com.huizu.common.utils.StringUtils;
import com.huizu.common.utils.UniqueStringGenerator;
import com.huizu.common.utils.dx.SecurityUtil;
import com.huizu.project.domain.*;
import com.huizu.project.mapper.*;
import com.huizu.project.service.IProUserService;
import com.huizu.project.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.Collator;
import java.util.*;
import java.util.stream.Collectors;

import static com.huizu.common.utils.PageUtils.startPage;

/**
 * 用户管理Service业务层处理
 * 
 * @author zhangmx
 * @date 2024-05-10
 */
@Service
public class ProUserServiceImpl implements IProUserService 
{
    @Autowired
    private ProUserMapper proUserMapper;

    @Autowired
    private ProUserTerMapper proUserTerMapper;

    @Autowired
    private ProBjMapper proBjMapper;

    @Autowired
    private ProXyMapper proXyMapper;

    @Autowired
    private ProZyMapper proZyMapper;

    @Autowired
    private ProNjMapper proNjMapper;

    @Autowired
    private ProXxtzMapper proXxtzMapper;

    @Autowired
    private ProLdMapper proLdMapper;

    @Autowired
    private ProLdzjMapper proLdzjMapper;

    @Autowired
    private ProLdcgMapper proLdcgMapper;

    @Autowired
    private ProLdgyMapper proLdgyMapper;

    @Autowired
    private ProUserDcMapper proUserDcMapper;

    @Autowired
    private ProNoticeMapper proNoticeMapper;

    @Autowired
    private SysUserAuthMapper sysUserAuthMapper;

    @Autowired
    private SysUserApiMapper sysUserMapper;

    @Autowired
    private RedisCache redisCache;


    @Autowired
    private RedisRank redisRank;
    /**
     * 查询用户管理
     * 
     * @param userId 用户管理主键
     * @return 用户管理
     */
    @Override
    public ProUser selectProUserByUserId(String userId)
    {
        return proUserMapper.selectProUserByUserId(userId);
    }

    public ProUser selectProUserByStNumber(String stNumber){

        return proUserMapper.selectProUserByStNumber(stNumber);
    }


    /**
     * 查询用户管理列表
     * 
     * @param proUser 用户管理
     * @return 用户管理
     */
    @Override
    public List<ProUser> selectProUserList(ProUser proUser)
    {
        return proUserMapper.selectProUserList(proUser);
    }

    /**
     * 新增用户管理
     * 
     * @param proUser 用户管理
     * @return 结果
     */
    @Override
    public int insertProUser(ProUser proUser)
    {
        ProUser proUser1 = proUserMapper.selectProUserByUserId(proUser.getStNumber());
        if (proUser1!=null)
            throw new ServiceException("学号已重复"+proUser.getStNumber());
        proUser.setUserId(proUser.getStNumber());
        String passwordMd5 = SecurityUtil.md5enc("LDJYxsd2024");//默认密码
        proUser.setPassword(passwordMd5);
        proUser.setCreateTime(DateUtils.getNowDate());

        return proUserMapper.insertProUser(proUser);
    }

    /**
     * 修改用户管理
     * 
     * @param proUser 用户管理
     * @return 结果
     */
    @Override
    public int updateProUser(ProUser proUser)
    {
        ProUser proUserByPhone = proUserMapper.selectProUserByPhone(proUser.getPhone());
        if (proUserByPhone != null && !proUser.getUserId().equals(proUserByPhone.getUserId())) {
            throw new ServiceException("手机号重复，请检查重新输入");
        }

        ProUser user = proUserMapper.selectProUserByUserId(proUser.getUserId());
        if (!user.getPhone().equals(proUser.getPhone())){
            proUser.setOpenId(null);
            proUserMapper.updateOpenId(null,proUser.getUserId());
        }
        return proUserMapper.updateProUser(proUser);
    }


    /**
     * 重置密码
     *
     * @param proUser 用户管理
     * @return 结果
     */
    public int resetPassword(ProUser proUser){
        String passwordMd5 = SecurityUtil.md5enc("LDJYxsd2024");
//        String userId = UniqueStringGenerator.generateUniqueString();
        proUser.setPassword(passwordMd5);
        return proUserMapper.updateProUser(proUser);
    }

    /**
     * 批量删除用户管理
     * 
     * @param userIds 需要删除的用户管理主键
     * @return 结果
     */
    @Override
    public int deleteProUserByUserIds(String[] userIds)
    {
        return proUserMapper.deleteProUserByUserIds(userIds);
    }

    /**
     * 删除用户管理信息
     * 
     * @param userId 用户管理主键
     * @return 结果
     */
    @Override
    public int deleteProUserByUserId(String userId)
    {
        return proUserMapper.deleteProUserByUserId(userId);
    }

    public List<Map<String,Object>> selectProUserListApi(ProUser proUser){
        List<ProUser> proUserList = proUserMapper.selectProUserList(proUser);
        List<Map<String, Object>> collect = proUserList.stream().map(entity -> {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", entity.getUserId());
            map.put("stNumber", entity.getStNumber());
            map.put("name", entity.getName());
            map.put("bjName", entity.getBjName());
            map.put("xyName", entity.getXyName());
            map.put("njName", entity.getNjName());
            map.put("xxName", entity.getXxName());
            return map;
        }).collect(Collectors.toList());
        return collect;
    }


    public AjaxResult login(ProUser proUserPram){
        ProUser proUser;
        if (StrUtil.isEmpty(proUserPram.getStNumber())){
            if (StrUtil.isEmpty(proUserPram.getPhone())){
                proUser = proUserMapper.selectProUserByOpenId(proUserPram.getOpenId());
                if (ObjectUtil.isEmpty(proUser)){
                    return AjaxResult.error("未授权登录");
                }

            }else{
                proUser = proUserMapper.selectProUserByPhone(proUserPram.getPhone());
                if (ObjectUtil.isEmpty(proUser)){
                    return AjaxResult.error("手机号不存在");
                }
                proUser.setOpenId(proUserPram.getOpenId());
                proUserMapper.updateProUser(proUser);
            }
        }else{
            proUser = proUserMapper.selectProUserByStNumber(proUserPram.getStNumber());
            if (ObjectUtil.isEmpty(proUser)){
                return AjaxResult.error("学号不存在");
            }
            boolean isPassword = SecurityUtil.authenticatePassword(proUser.getPassword(), proUserPram.getPassword());
            if (!isPassword){
                return AjaxResult.error("用户名或密码错误");
            }

        }
        String token = TokenUtils.generateAppToken(proUser.getUserId());
        proUser.setToken(token);
        return AjaxResult.success(proUser);
    }

    public AjaxResult loginDeputy(ProUser proUserPram) throws JsonProcessingException {
        ProUser proUser;
        if (StrUtil.isEmpty(proUserPram.getStNumber())){
            if (StrUtil.isEmpty(proUserPram.getPhone())){
                proUser = proUserMapper.selectProUserByOpenId(proUserPram.getOpenId());
                if (ObjectUtil.isEmpty(proUser)){
                    return AjaxResult.error("未授权登录");
                }

            }else{
                proUser = proUserMapper.selectProUserByPhone(proUserPram.getPhone());
                if (ObjectUtil.isEmpty(proUser)){
                    return AjaxResult.error("手机号不存在");
                }
                proUser.setOpenId(proUserPram.getOpenId());
                proUserMapper.updateProUser(proUser);
            }
        }else{
            proUser = proUserMapper.selectProUserByStNumber(proUserPram.getStNumber());
            if (ObjectUtil.isEmpty(proUser)){
                return AjaxResult.error("学号不存在");
            }
            boolean isPassword = SecurityUtil.authenticatePassword(proUser.getPassword(), proUserPram.getPassword());
            if (!isPassword){
                return AjaxResult.error("用户名或密码错误");
            }

        }
        String token = TokenUtils.generateAppToken(proUser.getUserId());
        proUser.setToken(token);

        // 通过base64进行加密
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(proUser);
        byte[] encodedBytes = Base64.getUrlEncoder().encode(json.getBytes(StandardCharsets.UTF_8));
        // 将字节数组转换为字符串
        String encodedString = new String(encodedBytes);
        return AjaxResult.success(encodedString);
    }

    public AjaxResult register(ProUser proUserPram){
        if (proUserPram.getStNumber()==null||"".equals(proUserPram.getStNumber()))
            throw new ServiceException("请输入学号");
        if (proUserPram.getPassword()==null||"".equals(proUserPram.getPassword()))
            throw new ServiceException("请输入密码");
        ProUser proUser = proUserMapper.selectProUserByStNumber(proUserPram.getStNumber());
        if (proUser!=null)
            return AjaxResult.error("用户已注册");
        String passwordMd5 = SecurityUtil.md5enc(proUserPram.getPassword());
        String userId = UniqueStringGenerator.generateUniqueString();
        proUserPram.setPassword(passwordMd5);
        proUserPram.setCreateTime(new Date());
        proUserPram.setUserId(userId);
        proUserPram.setNickName("学生"+proUserPram.getStNumber());
        int i = proUserMapper.insertProUser(proUserPram);
        return AjaxResult.success("注册成功");
    }

    /**
     * 忘记密码
     * @param proUserPram
     * @return
     */
    public AjaxResult updatePassword(ProUser proUserPram){
        if (proUserPram.getPhone()==null||"".equals(proUserPram.getPhone()))
            throw new ServiceException("请输入手机号");
        if (proUserPram.getPassword()==null||"".equals(proUserPram.getPassword()))
            throw new ServiceException("请输入新密码");
        Object s = redisCache.getCacheObject(proUserPram.getPhone());//获取验证码
        if (s!=null) {
            if (s.toString().equals(proUserPram.getCode())) {//判断验证码
                ProUser proUser = proUserMapper.selectProUserByPhone(proUserPram.getPhone());
                if (proUser==null)
                    return AjaxResult.error("手机号未注册");
                String passwordMd5 = SecurityUtil.md5enc(proUserPram.getPassword());
                proUser.setPassword(passwordMd5);
                proUserMapper.updateProUser(proUser);
                return AjaxResult.success("密码找回成功");
            }else {
                return AjaxResult.error("验证码错误");
            }
        }else {
            return AjaxResult.error("请先获取验证码");
        }
    }

    /**
     * 修改密码
     * @param proUserPram
     * @return
     */
    public AjaxResult updatePassword2(ProUser proUserPram){
        if (proUserPram.getPassword()==null||"".equals(proUserPram.getPassword()))
            throw new ServiceException("请输入旧密码");
        if (proUserPram.getPasswordNew()==null||"".equals(proUserPram.getPasswordNew()))
            throw new ServiceException("请输入新密码");

        if (!PassWordVerifyUtil.isValidPassword(proUserPram.getPasswordNew())) {
            throw new ServiceException("密码由6-30位的英文字母、数字和特殊字符组成，必须包含数字、小写字母和大写字母。");
        }

        ProUser proUser = proUserMapper.selectProUserByUserId(proUserPram.getUserId());
        if (proUser==null)
            return AjaxResult.error("用户异常");
        boolean isPassword = SecurityUtil.authenticatePassword(proUser.getPassword(), proUserPram.getPassword());
        if (!isPassword)
            return AjaxResult.error("原密码错误");
        String passwordMd5 = SecurityUtil.md5enc(proUserPram.getPasswordNew());
        proUser.setPassword(passwordMd5);
        proUserMapper.updateProUser(proUser);
        return AjaxResult.success("修改成功");

    }

    public AjaxResult loginTer(ProUserTer proUserPram){
        if (proUserPram.getJsNumber()==null||"".equals(proUserPram.getJsNumber()))
            throw new ServiceException("请输入职工号");
        if (proUserPram.getPassword()==null||"".equals(proUserPram.getPassword()))
            throw new ServiceException("请输入密码");
        SysUser sysUser = sysUserMapper.selectSysUserByJsNumber(proUserPram.getJsNumber());
        if (sysUser==null)
            return AjaxResult.error("职工号未注册");
        if ("1".equals(sysUser.getStatus())){
            return AjaxResult.error("职工已停用");
        }
        boolean isPassword = SecurityUtil.authenticatePassword(sysUser.getPassword(), proUserPram.getPassword());
        if (!isPassword)
            return AjaxResult.error("用户名或密码错误");
        String token = TokenUtils.generateAppToken(String.valueOf(sysUser.getUserId()));
        sysUser.setToken(token);
        return AjaxResult.success(sysUser);
    }

    /**
     * 登录教师端
     * @param sysUserPram
     * @return
     */
    public AjaxResult loginTer(SysUser sysUserPram){
        SysUser sysUser;
        if (StrUtil.isNotEmpty(sysUserPram.getPhone())){
            sysUser = sysUserMapper.selectSysUserByPhone(sysUserPram.getPhone());
            if (ObjectUtil.isEmpty(sysUser)){
                return AjaxResult.error("手机号不存在");
            }
            sysUser.setOpenId(sysUserPram.getOpenId());
            sysUserMapper.updateSysUser(sysUser);
        }else{
            sysUser =sysUserMapper.selectSysUserByOpenId(sysUserPram.getOpenId());
            if (ObjectUtil.isEmpty(sysUser)){
                throw new ServiceException("未授权登录");
            }
        }
        if ("1".equals(sysUser.getStatus())){
            return AjaxResult.error("职工已停用");
        }
        //boolean isPassword = SecurityUtil.authenticatePassword(sysUser.getUnPassword(), sysUserPram.getPassword());
        //if (!isPassword)
         //   return AjaxResult.error("用户名或密码错误");
        //将学号放进去
        String token = TokenUtils.generateAppToken(String.valueOf(sysUser.getUserId()));
        sysUser.setToken(token);
        return AjaxResult.success(sysUser);
    }

    /**
     * 修改教师端账号密码
     * @param proUserPram
     * @return
     */
    public AjaxResult updatePasswordTer(ProUserTer proUserPram){
        if (proUserPram.getPhone()==null||"".equals(proUserPram.getPhone()))
            throw new ServiceException("请输入手机号");
        if (proUserPram.getPassword()==null||"".equals(proUserPram.getPassword()))
            throw new ServiceException("请输入新密码");
        Object s = redisCache.getCacheObject(proUserPram.getPhone());//获取验证码
        if (s!=null) {
            if (s.toString().equals(proUserPram.getCode())) {//判断验证码
                ProUserTer proUser = proUserTerMapper.selectProUserByPhone(proUserPram.getPhone());
                if (proUser==null)
                    return AjaxResult.error("手机号未注册");
                String passwordMd5 = SecurityUtil.md5enc(proUserPram.getPassword());
                proUser.setPassword(passwordMd5);
                proUserTerMapper.updateProUserTer(proUser);
                return AjaxResult.success("密码找回成功");
            }else {
                return AjaxResult.error("验证码错误");
            }
        }else {
            return AjaxResult.error("请先获取验证码");
        }
    }

    /**
     * 修改教师端账号密码
     * @param
     * @return
     */
    public AjaxResult updatePasswordTer(SysUser sysUserPram){
        if (sysUserPram.getPhone()==null||"".equals(sysUserPram.getPhone()))
            throw new ServiceException("请输入手机号");
        if (sysUserPram.getPassword()==null||"".equals(sysUserPram.getPassword()))
            throw new ServiceException("请输入新密码");
        Object s = redisCache.getCacheObject(sysUserPram.getPhone());//获取验证码
        if (s!=null) {
            if (s.toString().equals(sysUserPram.getCode())) {//判断验证码
                SysUser sysUser = sysUserMapper.selectSysUserByPhone(sysUserPram.getPhone());
                if (sysUser==null)
                    return AjaxResult.error("手机号未注册");
                String passwordMd5 = SecurityUtil.md5enc(sysUserPram.getPassword());
                sysUser.setPassword(passwordMd5);
                sysUserMapper.updateSysUser(sysUser);
                return AjaxResult.success("密码找回成功");
            }else {
                return AjaxResult.error("验证码错误");
            }
        }else {
            return AjaxResult.error("请先获取验证码");
        }
    }

    public AjaxResult getBjTree(Map<String,Object> mapPram){
        String userId = String.valueOf(mapPram.get("userId"));
        //被授权的ID
        SysUserAuth sysUserAuthPram = new SysUserAuth();
        sysUserAuthPram.setUserId(Long.valueOf(userId));
        List<SysUserAuth> list = sysUserAuthMapper.selectSysUserAuthList(sysUserAuthPram);
        List<String> collectXyAuth = list.stream().filter(l -> "xy".equals(l.getType())).map(SysUserAuth::getBusId).collect(Collectors.toList());
        List<String> collectNjAuth = list.stream().filter(l -> "nj".equals(l.getType())).map(SysUserAuth::getBusId).collect(Collectors.toList());
        List<String> collectZyAuth = list.stream().filter(l -> "zy".equals(l.getType())).map(SysUserAuth::getBusId).collect(Collectors.toList());
        List<String> collectBJAuth = list.stream().filter(l -> "bj".equals(l.getType())).map(SysUserAuth::getBusId).collect(Collectors.toList());


        List<Map<String,Object>> respList = new ArrayList<>();
        List<ProXy> proXyList = proXyMapper.selectProXyList(new ProXy());
        List<ProNj> proNjs = proNjMapper.selectProNjList(new ProNj());
        List<ProZy> proZyList = proZyMapper.selectProZyList(new ProZy());
        List<ProBj> proBjs = proBjMapper.selectProBjListOptimized(new ProBj());
        proXyList = proXyList.stream().filter(proXy->collectXyAuth.contains(proXy.getId())).collect(Collectors.toList());
//        for (ProXy proXy : proXyList) {
//            List<Map<String,Object>> objectList = new ArrayList<>();
//            List<ProNj> proNjsTemp = proNjs.stream().filter(proNj-> collectNjAuth.contains(proNj.getId()))
//                                    .filter(proNj->proXy.getId().equals(proNj.getpId()))
//                                     .collect(Collectors.toList());
//            for (ProNj proNj : proNjsTemp) {
//                List<Map<String,Object>> objectList2 = new ArrayList<>();
//                List<ProZy> proZyListTemp = proZyList.stream().filter(proZy->collectZyAuth.contains(proZy.getId()))
//                        .filter(proZy->proZy.getpId().equals(proNj.getId()))
//                        .collect(Collectors.toList());
//                for (ProZy proZy : proZyListTemp) {
//                    List<ProBj> collectBj = proBjs.stream()
//                            .filter(l -> proZy.getId().equals(l.getpId()))
//                            .collect(Collectors.toList());
//                    //过滤
//                    List<Map<String, Object>> collect = collectBj.stream()
//                            .filter(l -> collectBJAuth.contains(l.getId()))
//                            .map(entity -> {
//                        Map<String, Object> map = new HashMap<>();
//                        map.put("id", entity.getId());
//                        map.put("name", entity.getName());
//                        map.put("type", "bj");
//                        return map;
//                    }).collect(Collectors.toList());
//                    Map<String,Object> objectMap = new HashMap<>();
//                    objectMap.put("childList",collect);
//                    objectMap.put("name",proZy.getName());
//                    objectMap.put("id",proZy.getId());
//                    objectMap.put("type","zy");
//                    objectList2.add(objectMap);
//                }
//                Map<String,Object> objectMap = new HashMap<>();
//                objectMap.put("childList",objectList2);
//                objectMap.put("name",proNj.getName());
//                objectMap.put("id",proNj.getId());
//                objectMap.put("type","nj");
//                objectList.add(objectMap);
//            }
//            Map<String,Object> objectMap = new HashMap<>();
//            objectMap.put("childList",objectList);
//            objectMap.put("name",proXy.getName());
//            objectMap.put("id",proXy.getId());
//            objectMap.put("type","xy");
//            respList.add(objectMap);
//        }
        // 将权限列表转换为LinkedHashSet以加速查找并保持顺序
        Set<String> collectNjAuthSet = new LinkedHashSet<>(collectNjAuth);
        Set<String> collectZyAuthSet = new LinkedHashSet<>(collectZyAuth);
        Set<String> collectBJAuthSet = new LinkedHashSet<>(collectBJAuth);

        for (ProXy proXy : proXyList) {
            List<Map<String, Object>> objectList = new ArrayList<>();

            // 提前过滤出与proXy相关的ProNj，并保持原始顺序
            List<ProNj> proNjsTemp = proNjs.stream()
                    .filter(proNj -> collectNjAuthSet.contains(proNj.getId()) && proXy.getId().equals(proNj.getpId()))
                    .collect(Collectors.toList());

            for (ProNj proNj : proNjsTemp) {
                List<Map<String, Object>> objectList2 = new ArrayList<>();

                // 提前过滤出与proNj相关的ProZy，并保持原始顺序
                List<ProZy> proZyListTemp = proZyList.stream()
                        .filter(proZy -> collectZyAuthSet.contains(proZy.getId()) && proZy.getpId().equals(proNj.getId()))
                        .collect(Collectors.toList());

                for (ProZy proZy : proZyListTemp) {
                    // 提前过滤出与proZy相关的ProBj，并保持原始顺序
                    List<ProBj> collectBj = proBjs.stream()
                            .filter(l -> collectBJAuthSet.contains(l.getId()) && proZy.getId().equals(l.getpId()))
                            .collect(Collectors.toList());

                    // 构建子集
                    List<Map<String, Object>> collect = collectBj.stream()
                            .map(entity -> {
                                Map<String, Object> map = new HashMap<>();
                                map.put("id", entity.getId());
                                map.put("name", entity.getName());
                                map.put("type", "bj");
                                return map;
                            }).collect(Collectors.toList());

                    Map<String, Object> objectMap = new HashMap<>();
                    objectMap.put("childList", collect);
                    objectMap.put("name", proZy.getName());
                    objectMap.put("id", proZy.getId());
                    objectMap.put("type", "zy");
                    objectList2.add(objectMap);
                }

                Map<String, Object> objectMap = new HashMap<>();
                objectMap.put("childList", objectList2);
                objectMap.put("name", proNj.getName());
                objectMap.put("id", proNj.getId());
                objectMap.put("type", "nj");
                objectList.add(objectMap);
            }

            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("childList", objectList);
            objectMap.put("name", proXy.getName());
            objectMap.put("id", proXy.getId());
            objectMap.put("type", "xy");
            respList.add(objectMap);
        }
        return AjaxResult.success(respList);
    }


    /**
     * 获取班级列表
     * @return
     */
    public List<ProBj> getBjList(ProBj proBjPram){
        List<ProBj> proBjs = proBjMapper.selectProBjList(proBjPram);
        for (ProBj proBj : proBjs) {
            ProUser proUser = new ProUser();
            proUser.setClId(proBj.getId());
            List<ProUser> users = proUserMapper.selectProUserList(proUser);
            BigDecimal totalPer = new BigDecimal(0);
            int totalNum = 0;
           for (ProUser user : users) {
                BigDecimal countPer = user.getJcldJdPer().multiply(BigDecimal.valueOf(0.48))
                        .add(user.getLdzjJdPer().multiply(BigDecimal.valueOf(0.16)))
                        .add(user.getLdcgJdPer().multiply(BigDecimal.valueOf(0.08)))
                        .add(user.getLdgyJdPer().multiply(BigDecimal.valueOf(0.08)))
                        .add(user.getLlcjJdPer().multiply(BigDecimal.valueOf(0.20)));
                totalNum++;
                totalPer = totalPer.add(countPer);
            }

            if (totalNum==0){
                proBj.setJdCount(BigDecimal.valueOf(0));
            }else {
                proBj.setJdCount(totalPer.divide(BigDecimal.valueOf(totalNum),2,RoundingMode.HALF_UP));
            }
//            proBj.setJdCount(new BigDecimal(0));
        }
        // 生成国内汉字首字母排序
        Collator instance = Collator.getInstance(Locale.CHINA);
        //班级排序
        if (StringUtils.isNotEmpty(proBjPram.getBjNameSort())) {
            if ("asc".equals(proBjPram.getBjNameSort())) {
                proBjs.sort(Comparator.comparing(ProBj::getName,
                        Comparator.nullsLast(instance)));
            } else if ("desc".equals(proBjPram.getBjNameSort())) {
                proBjs.sort(Comparator.comparing(ProBj::getName,
                        Comparator.nullsLast(instance)).reversed());
            }
        }
        //人数排序
        if (StringUtils.isNotEmpty(proBjPram.getUserCountSort())) {
            if ("asc".equals(proBjPram.getUserCountSort())) {
               return proBjs.stream().sorted(Comparator.comparing(ProBj::getUserCount))
                        .collect(Collectors.toList());
            } else if ("desc".equals(proBjPram.getUserCountSort())) {
                return proBjs.stream().sorted(Comparator.comparing(ProBj::getUserCount).reversed())
                        .collect(Collectors.toList());
            }
        }
        //总进度排序
        if (StringUtils.isNotEmpty(proBjPram.getJdCountSort())) {
            if ("asc".equals(proBjPram.getJdCountSort())) {
                return proBjs.stream().sorted(Comparator.comparing(ProBj::getJdCount))
                        .collect(Collectors.toList());
            } else if ("desc".equals(proBjPram.getJdCountSort())) {
                return proBjs.stream().sorted(Comparator.comparing(ProBj::getJdCount).reversed())
                        .collect(Collectors.toList());
            }
        }

        return proBjs;
    }

    public AjaxResult getBjById(String id){
        ProBj proBj = proBjMapper.selectProBjById(id);
        if (proBj==null)
            return AjaxResult.error("所选班级不存在");
        ProUser proUser = new ProUser();
        proUser.setClId(id);
        List<ProUser> users = proUserMapper.selectProUserList(proUser);
        int count = 0;
        int wcCount = 0;
        int jcldJdCount = 0;
        int ldzjJdCount = 0;
        int ldgyJdCount = 0;
        int ldcgJdCount = 0;

       //进度 晚点处理
        for (ProUser sysUser : users) {
            count++;
            if (sysUser.getJdCount()==2)
                wcCount++;
            if (sysUser.getJcldJdCount()==2)
                jcldJdCount++;
            if (sysUser.getLdzjJdCount()==2)
                ldzjJdCount++;
            if (sysUser.getLdgyJdCount()==2)
                ldgyJdCount++;
            if (sysUser.getLdcgJdCount()==2)
                ldcgJdCount++;
        }
        proBj.setUserCount(count);
        proBj.setWcCount(wcCount);
        proBj.setJcldJdCount(jcldJdCount);
        proBj.setLdzjJdCount(ldzjJdCount);
        proBj.setLdgyJdCount(ldgyJdCount);
        proBj.setLdcgJdCount(ldcgJdCount);
        proBj.setJdCount(count == 0 ? new BigDecimal(0) : BigDecimal.valueOf(wcCount/count).multiply(new BigDecimal("100")));
        return AjaxResult.success(proBj);
    }


    /**
     * 查询用户管理列表
     *
     * @param proUser 用户管理
     * @return 用户管理集合
     */
    public List<ProUser> listSt(ProUser proUser){
        List<ProUser> proUserList = proUserMapper.selectProUserList(proUser);
        for (ProUser user : proUserList) {

            BigDecimal jcldCj = user.getUserjcldCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal cgCj = user.getUserldcgCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal gyCj = user.getUserldgyCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal zjCj = user.getUserldzjCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal llCj = user.getUserllCj().setScale(2, RoundingMode.HALF_UP);

            BigDecimal jcldCjZS = jcldCj.multiply(BigDecimal.valueOf(0.6)).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldzjCjZS = zjCj.multiply((BigDecimal.valueOf(0.2))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldgyCjZS = gyCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldcgCjZS = cgCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal countSjZs = jcldCjZS.add(ldzjCjZS).add(ldgyCjZS).add(ldcgCjZS);
            BigDecimal countLLZs = llCj;


            BigDecimal countPer = user.getJcldJdPer().multiply(BigDecimal.valueOf(0.48))
                    .add(user.getLdzjJdPer().multiply(BigDecimal.valueOf(0.16)))
                    .add(user.getLdcgJdPer().multiply(BigDecimal.valueOf(0.08)))
                    .add(user.getLdgyJdPer().multiply(BigDecimal.valueOf(0.08)))
                    .add(user.getLlcjJdPer().multiply(BigDecimal.valueOf(0.20)));

            user.setCountCj(countLLZs.multiply(BigDecimal.valueOf(0.2)).add(countSjZs.multiply(BigDecimal.valueOf(0.8))));
            user.setCountLLPer(user.getLlcjJdPer());
            user.setCountSjPer(user.getCountSjPer());
//            user.setCountPer(countLLPer.multiply(BigDecimal.valueOf(0.2)).add(countSjPer.multiply(BigDecimal.valueOf(0.8))));
            user.setCountPer(countPer);
        }
        return proUserList;
    }

    /**
     * 获取总成绩
     * @param map
     * @return
     */
    public AjaxResult getCountCj(Map<String,Object> map){
        String userId = String.valueOf(map.get("userId"));
        Map<String,Object> respMap = new HashMap<>();

        ProUser proUser = proUserMapper.selectProUserByUserId(userId);
        if (proUser==null)
            return AjaxResult.error("所选学生不存在");

        BigDecimal jcldCj = proUser.getUserjcldCj().setScale(2, RoundingMode.HALF_UP);
        BigDecimal cgCj = proUser.getUserldcgCj().setScale(2, RoundingMode.HALF_UP);
        BigDecimal gyCj = proUser.getUserldgyCj().setScale(2, RoundingMode.HALF_UP);
        BigDecimal zjCj = proUser.getUserldzjCj().setScale(2, RoundingMode.HALF_UP);
        BigDecimal llCj = proUser.getUserllCj().setScale(2, RoundingMode.HALF_UP);

        BigDecimal jcldCjZS = jcldCj.multiply(BigDecimal.valueOf(0.6)).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldzjCjZS = zjCj.multiply((BigDecimal.valueOf(0.2))).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldgyCjZS = gyCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldcgCjZS = cgCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
        BigDecimal countSjZs = jcldCjZS.add(ldzjCjZS).add(ldgyCjZS).add(ldcgCjZS);
        BigDecimal countLLZs = llCj;



        BigDecimal countPer = proUser.getJcldJdPer().multiply(BigDecimal.valueOf(0.48))
                .add(proUser.getLdzjJdPer().multiply(BigDecimal.valueOf(0.16)))
                .add(proUser.getLdcgJdPer().multiply(BigDecimal.valueOf(0.08)))
                .add(proUser.getLdgyJdPer().multiply(BigDecimal.valueOf(0.08)))
                .add(proUser.getLlcjJdPer().multiply(BigDecimal.valueOf(0.20)));

        //该生的基础劳动进度*48%+劳动总结报告进度*16%+劳动成果进度*8%+社会公益劳动进度*8%+理论成绩进度*20%


//        BigDecimal llcjPer = new BigDecimal(100);


        Map<String,Object> objectMap = new HashMap<>();
        Map<String,Object> objectMap2 = new HashMap<>();

        List<Object> list1 = new ArrayList<>();
        List<Object> list2 = new ArrayList<>();
        List<Object> list3 = new ArrayList<>();
        List<Object> list4 = new ArrayList<>();

        List<Object> list5 = new ArrayList<>();
        List<Object> list6 = new ArrayList<>();


        list1.add("类型");
        list1.add("基础劳动");

        list1.add("社会公益劳动");
        list1.add("劳动成果");
        list1.add("劳动总结报告");
        list1.add("实践成绩");

        list2.add("原始成绩");
        list2.add(proUser.getUserjcldCj());

        list2.add(proUser.getUserldgyCj());
        list2.add(proUser.getUserldcgCj());
        list2.add(proUser.getUserldzjCj());
        list2.add("/");

        list3.add("权重因子");
        list3.add("60%");

        list3.add("10%");
        list3.add("10%");
        list3.add("20%");
        list3.add("/");

        list4.add("折算成绩");
        list4.add(jcldCjZS);

        list4.add(ldgyCjZS);
        list4.add(ldcgCjZS);
        list4.add(ldzjCjZS);
        list4.add(countSjZs);

        objectMap.put("list1",list1);
        objectMap.put("list2",list2);
        objectMap.put("list3",list3);
        objectMap.put("list4",list4);


        list5.add("劳动教育总成绩");
        list5.add("理论成绩×20%");
        list5.add("实践成绩×80%");

        list6.add(countLLZs.multiply(BigDecimal.valueOf(0.2)).add(countSjZs.multiply(BigDecimal.valueOf(0.8))));
        list6.add(countLLZs.multiply(BigDecimal.valueOf(0.2)));
        list6.add(countSjZs.multiply(BigDecimal.valueOf(0.8)));
        objectMap2.put("list1",list5);
        objectMap2.put("list2",list6);


        respMap.put("sjcj",objectMap);
        respMap.put("llcj",llCj);
        respMap.put("ldjy",objectMap2);
        respMap.put("user",proUser);
        return AjaxResult.success(respMap);
    }


    /**
     * 排行榜
     * @param mapPram
     * @return
     */
    public List<ProUser> listPhb(ProUser mapPram){
        //redis 实现排序
        if (StrUtil.isEmpty(mapPram.getStNumberOrName())){
            redisRank.removeRankUserCj(mapPram.getXyId());
            redisRank.removeRankLdCj(mapPram.getXyId());
            redisRank.removeRankLlCj(mapPram.getXyId());
            List<ProUser> list = proUserMapper.selectRank(mapPram.getXyId());
            for (ProUser proUser: list) {
                redisRank.addBatchLdCj(mapPram.getXyId(),proUser.getUserId(),proUser.getUserLdCj()==null ? 0.00: proUser.getUserLdCj().doubleValue());
                redisRank.addBatchUserCj(mapPram.getXyId(),proUser.getUserId(),proUser.getUserCj()==null ? 0.00: proUser.getUserCj().doubleValue());
                redisRank.addBatchLlCj(mapPram.getXyId(),proUser.getUserId(),proUser.getUserllCj()==null ? 0.00: proUser.getUserllCj().doubleValue());
            }
        }

        String isSort = mapPram.getIsSort();
        startPage();
        List<ProUser> proUserList = proUserMapper.selectProUserList(mapPram);
        proUserList.stream().forEach(entity -> {
            BigDecimal jcldCj = entity.getUserjcldCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal cgCj = entity.getUserldcgCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal gyCj = entity.getUserldgyCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal zjCj = entity.getUserldzjCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal llCj = entity.getUserllCj().setScale(2, RoundingMode.HALF_UP);
            BigDecimal jcldCjZS = jcldCj.multiply(BigDecimal.valueOf(0.6)).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldzjCjZS = zjCj.multiply((BigDecimal.valueOf(0.2))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldgyCjZS = gyCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal ldcgCjZS = cgCj.multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
            BigDecimal countSjZs = jcldCjZS.add(ldzjCjZS).add(ldgyCjZS).add(ldcgCjZS);
            BigDecimal countLLZs = llCj;


            countLLZs = countLLZs.multiply(BigDecimal.valueOf(0.2)).setScale(0, RoundingMode.HALF_UP);
            countSjZs = countSjZs.multiply(BigDecimal.valueOf(0.8)).setScale(0, RoundingMode.HALF_UP);
        if ("1".equals(isSort)){
            entity.setDfCount(countSjZs.add(countLLZs));
            entity.setRank(redisRank.getRankUserCj(mapPram.getXyId(),entity.getUserId())+1);
            }else if ("2".equals(isSort)){
            entity.setDfCount(countSjZs);
            entity.setRank(redisRank.getRankLdCj(mapPram.getXyId(),entity.getUserId())+1);
            }else if ("3".equals(isSort)){
            entity.setDfCount(countLLZs);
            entity.setRank(redisRank.getRankLlCj(mapPram.getXyId(),entity.getUserId())+1);
            }
        });
        return proUserList;
    }

    /**
     * 排行榜     
     * @param mapPram
     * @return
     */
    public AjaxResult listPhbByUser(Map<String,Object> mapPram){
        String userId = String.valueOf(mapPram.get("userId"));
        ProUser proUser = proUserMapper.selectProUserByUserId(userId);
        String xyId = proUser.getXyId();
        String zyId = proUser.getZyId();
        String njId = proUser.getNjId();
        String bjId = proUser.getClId();
        //理论积分
        int userLlPoints = proUser.getUserllPoints();


        BigDecimal jcldCjZS = proUser.getUserjcldCj().multiply(BigDecimal.valueOf(0.6)).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldzjCjZS = proUser.getUserldzjCj().multiply((BigDecimal.valueOf(0.2))).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldgyCjZS = proUser.getUserldgyCj().multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
        BigDecimal ldcgCjZS = proUser.getUserldcgCj().multiply((BigDecimal.valueOf(0.1))).setScale(2, RoundingMode.HALF_UP);
        //劳动成绩
        BigDecimal countSjZs = jcldCjZS.add(ldzjCjZS).add(ldgyCjZS).add(ldcgCjZS);
        //理论成绩
        BigDecimal countLLZs = proUser.getUserllCj();
        //总成绩
        BigDecimal userCj = countSjZs.multiply(BigDecimal.valueOf(0.8)).add(countLLZs.multiply(BigDecimal.valueOf(0.2))).setScale(2, RoundingMode.HALF_UP);



        Map<String,Integer> respMap = new HashMap<>();
        //xy  zy  nj  bj
        String type = String.valueOf(mapPram.get("type"));
        Integer llPh=0;
        Integer jfPh=0;
        Integer zfph=0;
       if ("xx".equals(type)){
           llPh = proUserMapper.getRankByXyLl(xyId,userLlPoints);
           jfPh = proUserMapper.getRankByXyLd(xyId,countSjZs);
           zfph = proUserMapper.getRankByXyCj(xyId,userCj);
       }else if ("zy".equals(type)){
           llPh = proUserMapper.getRankByZyLl(zyId,userLlPoints);
           jfPh = proUserMapper.getRankByZyLd(zyId,countSjZs);
           zfph = proUserMapper.getRankByZyCj(zyId,userCj);

       } else if ("nj".equals(type)) {
           llPh = proUserMapper.getRankByNjLl(njId,userLlPoints);
           jfPh = proUserMapper.getRankByNjLd(njId,countSjZs);
           zfph = proUserMapper.getRankByNjCj(njId,userCj);

       } else if ("bj".equals(type)) {
           llPh = proUserMapper.getRankByBjLl(bjId,userLlPoints);
           jfPh = proUserMapper.getRankByBjLd(bjId,countSjZs);
           zfph = proUserMapper.getRankByBjCj(bjId,userCj);

       }
        respMap.put("llph",(llPh==null? 0:llPh)+1);
        respMap.put("jfph",(jfPh==null? 0:jfPh)+1);
        respMap.put("zfph",(zfph==null? 0:zfph)+1);
        return AjaxResult.success(respMap);
    }

    public List<Map<String,Object>> ldListUser(Map<String,Object> map){
        List<Map<String,Object>> respMap = new ArrayList<>();
        String userId = String.valueOf(map.get("userId"));
        ProLd proLdPram = new ProLd();
        ProLdcg proLdcgPram = new ProLdcg();
        ProLdgy proLdgyPram = new ProLdgy();
        ProLdzj proLdzjPram = new ProLdzj();
        proLdPram.setUserId(userId);
        proLdcgPram.setUserId(userId);
        proLdgyPram.setUserId(userId);
        proLdzjPram.setUserId(userId);
        List<ProLd> proLds = proLdMapper.selectProLdList(proLdPram);
        List<ProLdcg> proLdcgs = proLdcgMapper.selectProLdcgList(proLdcgPram);
        List<ProLdgy> proLdgys = proLdgyMapper.selectProLdgyList(proLdgyPram);
        List<ProLdzj> proLdzjs = proLdzjMapper.selectProLdzjList(proLdzjPram);
        List<Map<String, Object>> collectLd = proLds.stream().map(entity -> {
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("bgType", "1");
            objectMap.put("id", entity.getId());
            objectMap.put("type", entity.getType());
            objectMap.put("typeName", entity.getTypeName());
            objectMap.put("markNumber", entity.getMarkNumber());
            objectMap.put("createTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, entity.getCreateTime()));
            return objectMap;
        }).collect(Collectors.toList());

        List<Map<String, Object>> collectLdZj = proLdzjs.stream().map(entity -> {
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("bgType", "2");
            objectMap.put("id", entity.getId());
            objectMap.put("type", "");
            objectMap.put("typeName", "劳动总结报告");
            objectMap.put("markNumber", entity.getMarkNumber());
            objectMap.put("createTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, entity.getCreateTime()));
            return objectMap;
        }).collect(Collectors.toList());

        List<Map<String, Object>> collectLdGy = proLdgys.stream().map(entity -> {
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("bgType", "3");
            objectMap.put("id", entity.getId());
            objectMap.put("type", "");
            objectMap.put("typeName", "社会公益劳动");
            objectMap.put("markNumber", entity.getMarkNumber());
            objectMap.put("createTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, entity.getCreateTime()));
            return objectMap;
        }).collect(Collectors.toList());

        List<Map<String, Object>> collectLdCg = proLdcgs.stream().map(entity -> {
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("bgType", "4");
            objectMap.put("id", entity.getId());
            objectMap.put("type", "");
            objectMap.put("typeName", "劳动成果报告");
            objectMap.put("markNumber", entity.getMarkNumber());
            objectMap.put("createTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, entity.getCreateTime()));
            return objectMap;
        }).collect(Collectors.toList());

        respMap.addAll(collectLd);
        respMap.addAll(collectLdZj);
        respMap.addAll(collectLdGy);
        respMap.addAll(collectLdCg);
        return respMap;
    }

    /**
     * 获取消息通知
     * @param map
     * @return
     */
    public AjaxResult listMessage(Map<String, Object> map){
        List<Map<String,Object>> respList = new ArrayList<>();
        String userId = String.valueOf(map.get("userId"));

        ProLd proLdPram = new ProLd();
        proLdPram.setBeUserId(userId);
        proLdPram.setUserId(userId);
        proLdPram.setStatus("3");
        List<ProLd> proLds = proLdMapper.selectProLdList(proLdPram);
        long count = proLds.stream().filter(l -> l.getXxStatus() == 0).count();

        ProNotice proNoticePram = new ProNotice();
        proNoticePram.setBeUserId(userId);
        List<ProNotice> proNotices = proNoticeMapper.selectProNoticeList(proNoticePram);
        long count2 = proNotices.stream().filter(l -> l.getXxStatus() == 0).count();

        Map<String,Object> objectMap = new HashMap<>();
        objectMap.put("name","待办事项");
        objectMap.put("type","1");
        objectMap.put("count",count);

        Map<String,Object> objectMap2 = new HashMap<>();
        objectMap2.put("name","通知公告");
        objectMap.put("type","2");
        objectMap2.put("count",count2);

        Map<String,Object> objectMap3 = new HashMap<>();
        objectMap3.put("name","系统消息");
        objectMap.put("type","3");
        objectMap3.put("count",count2);

        respList.add(objectMap);
        respList.add(objectMap2);
        respList.add(objectMap3);
        return AjaxResult.success(respList);
    }

    /**
     * 获取驳回事项列表
     * @param map
     * @return
     */
    public List<Map<String,Object>> listLdReject(Map<String,Object> map){
        String userId = String.valueOf(map.get("userId"));
        ProLd proLdPram = new ProLd();
        proLdPram.setUserId(userId);
        proLdPram.setBeUserId(userId);
        proLdPram.setStatus("3");
        List<ProLd> proLds = proLdMapper.selectProLdList(proLdPram);
        List<Map<String, Object>> collect = proLds.stream().map(entity -> {
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("id", entity.getId());
            objectMap.put("bgType", "1");
            objectMap.put("type", entity.getType());
            objectMap.put("typeName", entity.getTypeName());
            objectMap.put("createTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, entity.getCreateTime()));
            return objectMap;
        }).collect(Collectors.toList());
        return collect;
    }

    public AjaxResult bindWx(Map<String,Object> map){
        return AjaxResult.success("绑定成功");
    }

    public List<ProXy> getXyList(ProXy proXy){
        return proXyMapper.selectProXyList(proXy);
    }

    public List<ProZy> getZyList(ProZy proZy){
        return proZyMapper.selectProZyList(proZy);
    }

    public List<ProNj> getNjList(ProNj proNj){
        return proNjMapper.selectProNjList(proNj);
    }

    @Override
    public List<ProUser> selectProUserByNumberNotUserId(ProUser proUser) {

        return proUserMapper.selectProUserByNumberNotUserId(proUser.getStNumber(),proUser.getUserId());
    }

    @Override
    public SysUser selectSysUserByJsNumber(String jsNumber){

      return   sysUserMapper.selectSysUserByJsNumber(jsNumber);

    }

    @Override
    public ProUser selectProUserByOpenId(String openId){
        return  proUserMapper.selectProUserByOpenId(openId);
    }

    @Override
    public SysUser selectSysUserByOpenId(String openId){
        return  sysUserMapper.selectSysUserByOpenId(openId);
    }

    @Override
    public AjaxResult relieveBinding(ProUser proUser) {
        proUserMapper.relieveBinding(proUser);
        return AjaxResult.success("解除绑定成功");
    }


}
